package org.huamoxi.listener;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import org.huamoxi.entity.MarketItem;
import org.huamoxi.start.PluginMain;
import org.huamoxi.util.DataSQLUtil;
import org.huamoxi.util.InventoryUtil;

import java.math.BigDecimal;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MarketInventoryClickListener implements Listener {

    private final FileConfiguration config;
    private final Boolean isRunning;
    private final Connection dbConnection;

    public MarketInventoryClickListener(JavaPlugin plugin, Connection dbConnection) {
        this.config = plugin.getConfig();
        this.isRunning = Boolean.valueOf(this.config.getBoolean("isRunning"));
        this.dbConnection = dbConnection;
    }

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        BigDecimal money = DataSQLUtil.hasIncomeRecord(dbConnection, player.getUniqueId());
        if (money != null) {
            BigDecimal newBalance = PluginMain.increasePlayerMoney(player, money);
            String sellOutSuccessMsg = config.getString("notice.sellOutSuccessMsg");
            player.sendMessage(sellOutSuccessMsg
                    .replace("{money}", money + "")
                    .replace("{balance}", newBalance + ""));
        }
    }

    @EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        if (!isRunning) {
            return;
        }
        Inventory eventInventory = event.getInventory();
        if (eventInventory.getType() == InventoryType.CHEST) {
            if (InventoryUtil.checkMarketInventory(eventInventory, config)) {
                // 如果打开的是插件inventory就禁用默认行为
                event.setCancelled(true);

                // 判断点击的东西是否合法(是否在容器内、是否点到了物品、是否是插件inventory里的物品)
                // 点击inventory格子以外的
                ItemStack selectedItem = event.getCurrentItem();
                if (selectedItem == null) {
                    return;
                }
                // 点击inventory空白的slot格子
                ItemMeta selectedItemMeta = selectedItem.getItemMeta();
                if (selectedItemMeta == null) {
                    return;
                }
                // 默认是查看市场的商品列表
                Player player = (Player) event.getWhoClicked();
                int rawSlot = event.getRawSlot();
                if (rawSlot == 49) {
                    return;
                }
                if (rawSlot == 48 || rawSlot == 50) {
                    DataSQLUtil.updateCurrentByPlayer(dbConnection, player, 1);
                    ItemStack sign = new ItemStack(Material.OAK_SIGN);
                    ItemMeta signItemMeta = sign.getItemMeta();
                    signItemMeta.setDisplayName(config.getString("notice.signTitle"));
                    List<String> signLoreList = new ArrayList<>();
                    if (rawSlot == 48) {
                        flushMarketItem(eventInventory, true, player, 1, config, dbConnection);
                        DataSQLUtil.updateTypeByPlayer(dbConnection, player, 1);
                        signLoreList.add(config.getString("notice.seeOtherMarketItemMsg"));
                    } else {
                        flushMarketItem(eventInventory, false, player, 1, config, dbConnection);
                        DataSQLUtil.updateTypeByPlayer(dbConnection, player, 2);
                        signLoreList.add(config.getString("notice.seeMineMarketItemMsg"));
                    }
                    if (!"".equals(config.getString("notice.signContent1"))) {
                        signLoreList.add(config.getString("notice.signContent1"));
                    }
                    if (!"".equals(config.getString("notice.signContent2"))) {
                        signLoreList.add(config.getString("notice.signContent2"));
                    }
                    if (!"".equals(config.getString("notice.signContent3"))) {
                        signLoreList.add(config.getString("notice.signContent3"));
                    }
                    signItemMeta.setLore(signLoreList);
                    sign.setItemMeta(signItemMeta);
                    eventInventory.setItem(49, sign);
                    return;
                }

                boolean isOther = DataSQLUtil.getTypeFromMarketPageByUID(dbConnection, player.getUniqueId());
                Integer current = DataSQLUtil.getCurrentByUID(dbConnection, player.getUniqueId());
                if (rawSlot >= 0 && rawSlot < 36) {
                    if (!event.isShiftClick()) {
                        return;
                    }
                    if (event.isLeftClick()) {
                        // 单个购买
                        buyItemHandler(dbConnection, current, config, player, eventInventory, rawSlot, "single");
                    } else if (event.isRightClick()) {
                        // 全购买
                        buyItemHandler(dbConnection, current, config, player, eventInventory, rawSlot, "all");
                    }
                }

                if (rawSlot == 45 || rawSlot == 53) {
                    Inventory inventory = event.getInventory();
                    // 分页查询商品
                    List<String> selectedItemLoreList = selectedItemMeta.getLore();
                    // 查询 MarketItem 最大页数
                    Integer maxPage = DataSQLUtil.getMaxPage(dbConnection, config);
                    if (selectedItemMeta.getDisplayName().equals(config.getString("notice.lastPageMsg"))) {
                        if (selectedItemLoreList.get(0).equals(config.getString("notice.showLastPageMsg"))) {
                            if (current == 1) {
                                return;
                            }
                            // 切换商品列表
                            flushMarketItem(eventInventory, isOther, player, current - 1, config, dbConnection);
                            DataSQLUtil.updateCurrentByPlayer(dbConnection, player, current - 1);
                            // 改变分页纸张
                            setPagePaper(config, current - 1, maxPage, inventory);
                        }
                    } else if (selectedItemMeta.getDisplayName().equals(config.getString("notice.nextPageMsg"))) {
                        if (selectedItemLoreList.get(0).equals(config.getString("notice.showNextPageMsg"))) {
                            if (current == maxPage) {
                                return;
                            }
                            // 切换商品列表
                            flushMarketItem(eventInventory, isOther, player, current + 1, config, dbConnection);
                            DataSQLUtil.updateCurrentByPlayer(dbConnection, player, current + 1);
                            // 改变分页纸张
                            setPagePaper(config, current + 1, maxPage, inventory);
                        }
                    }
                }
            }
        }
    }

    private static void buyItemHandler (Connection dbConnection, Integer current, FileConfiguration config, Player player, Inventory eventInventory, int rawSlot, String buyType) {
        MarketItem marketItem = DataSQLUtil.getMarketItemId(dbConnection, current, config.getInt("market.pageSize"), rawSlot);
        if (marketItem == null) {
            return;
        }
        boolean isOther = DataSQLUtil.getTypeFromMarketPageByUID(dbConnection, player.getUniqueId());
        if (player.getUniqueId().toString().equals(marketItem.getPlayerUID())) {
            ItemStack itemStack = DataSQLUtil.getItemStackByMarketItenId(dbConnection, marketItem.getId());
            if (buyType.equals("single")) {
                if (marketItem.getQuantity() == 1) {
                    DataSQLUtil.deleteMarketItemById(dbConnection, marketItem.getId());
                } else {
                    DataSQLUtil.updateMarketItemById(dbConnection, marketItem.getId());
                }
                itemStack.setAmount(1);
                player.getInventory().addItem(itemStack);
            } else if (buyType.equals("all")) {
                DataSQLUtil.deleteMarketItemById(dbConnection, marketItem.getId());
                player.getInventory().addItem(itemStack);
            }
            flushMarketItem(eventInventory, isOther, player, current, config, dbConnection);
            return;
        }

        BigDecimal price = DataSQLUtil.getPriceById(dbConnection, marketItem.getId());
        BigDecimal playerMoney = PluginMain.getPlayerMoney(player);
        int comparisonResult = playerMoney.compareTo(price);
        if (comparisonResult >= 0) {
            int i = 0;
            BigDecimal balance = BigDecimal.ZERO;
            ItemStack itemStack = DataSQLUtil.getItemStackByMarketItenId(dbConnection, marketItem.getId());
            if (buyType.equals("single")) {
                itemStack.setAmount(1);
                // 扣除玩家金额
                balance = PluginMain.reducePlayerMoney(player, price);
                // 商品数量减1
                if (marketItem.getQuantity() == 1) {
                    i = DataSQLUtil.deleteMarketItemById(dbConnection, marketItem.getId());
                } else {
                    i = DataSQLUtil.updateMarketItemById(dbConnection, marketItem.getId());
                }
                // 刷新商品列表
                flushMarketItem(eventInventory, isOther, player, current, config, dbConnection);
            } else if (buyType.equals("all")) {
                // 扣除玩家金额
                balance = PluginMain.reducePlayerMoney(player, price.multiply(BigDecimal.valueOf(itemStack.getAmount())));
                // 商品清空
                i = DataSQLUtil.deleteMarketItemById(dbConnection, marketItem.getId());
                // 刷新商品列表
                flushMarketItem(eventInventory, isOther, player, current, config, dbConnection);
            }

            String priceStr = price.scale() == 0 ? String.valueOf(price.intValue()): price.toPlainString();

            // 获取商家
            Player seller = Bukkit.getPlayer(UUID.fromString(marketItem.getPlayerUID()));
            if (seller != null) {
                // 在线
                BigDecimal newBalance = PluginMain.increasePlayerMoney(seller, price);
                String sellOutSuccessMsg = config.getString("notice.sellOutSuccessMsg");
                String newBalanceStr = newBalance.scale() == 0 ? String.valueOf(newBalance.intValue()): newBalance.toPlainString();
                seller.sendMessage(config.getString("market.name") + sellOutSuccessMsg
                        .replace("{money}", priceStr + config.getString("market.priceSymbol"))
                        .replace("{balance}", newBalanceStr + config.getString("market.priceSymbol"))
                );
            } else {
                // 不在线
                DataSQLUtil.saveMoneyRecord(dbConnection, player.getUniqueId(), playerMoney);
            }

            if (i > 0) {
                player.getInventory().addItem(itemStack);
                String buySuccessMsg = config.getString("notice.buySuccessMsg");
                String balanceStr = balance.scale() == 0 ? String.valueOf(balance.intValue()): balance.toPlainString();
                player.sendMessage(config.getString("market.name")
                        + buySuccessMsg.replace("{money}", priceStr
                        + config.getString("market.priceSymbol")).replace("{balance}", balanceStr + config.getString("market.priceSymbol")));
            } else {
                player.sendMessage(config.getString("market.name") + config.getString("notice.buyFairNoItemMsg"));
            }
        } else {
            player.sendMessage(config.getString("market.name") + config.getString("notice.buyFairNotEnoughMoneyMsg"));
            // 切换商品列表
            flushMarketItem(eventInventory, true, player, current, config, dbConnection);
        }
    }

    /**
     * 刷新商品
     */
    private static void flushMarketItem(Inventory inventory, boolean isOther, Player player, Integer pageNo, FileConfiguration config, Connection dbConnection) {
        // 切换商品列表
        int pageSize = config.getInt("market.pageSize");
        for (int i = 0; i < pageSize; i++) {
            inventory.clear(i);
        }
        DataSQLUtil.setInventoryByCurrent(player, isOther, inventory, config, pageNo, pageSize, dbConnection);
    }

    private static void setPagePaper (FileConfiguration config, Integer current, Integer maxPage, Inventory inventory) {
        ItemStack lastPaper = new ItemStack(Material.PAPER);
        ItemMeta lastPaperMeta = lastPaper.getItemMeta();
        if (lastPaperMeta != null) {
            lastPaperMeta.setDisplayName(config.getString("notice.lastPageMsg"));

            List<String> loreList = new ArrayList<>();
            if (current == 1) {
                loreList.add(config.getString("notice.isStartPageMsg"));
            } else {
                loreList.add(config.getString("notice.showLastPageMsg"));
            }
            lastPaperMeta.setLore(loreList);
            lastPaper.setItemMeta(lastPaperMeta);
        }
        inventory.setItem(45, lastPaper);

        ItemStack nextPaper = new ItemStack(Material.PAPER);
        ItemMeta nextPaperMeta = nextPaper.getItemMeta();
        if (nextPaperMeta != null) {
            nextPaperMeta.setDisplayName(config.getString("notice.nextPageMsg"));

            List<String> loreList = new ArrayList<>();
            if (current == maxPage) {
                loreList.add(config.getString("notice.isEndPageMsg"));
            } else {
                loreList.add(config.getString("notice.showNextPageMsg"));
            }
            nextPaperMeta.setLore(loreList);
            nextPaper.setItemMeta(nextPaperMeta);
        }
        inventory.setItem(53, nextPaper);
    }
}
